"""
Given a string, find the length of the longest substring without repeating characters.

Example 1:
Input: "abcabcbb"
Output: 3
Explanation: The answer is "abc", with the length of 3.

Example 2:
Input: "bbbbb"
Output: 1
Explanation: The answer is "b", with the length of 1.

Example 3:
Input: "pwwkew"
Output: 3
Explanation: The answer is "wke", with the length of 3.
             Note that the answer must be a substring, "pwke" is a subsequence and not a substring.

题目大意
在一个字符串中寻找没有重复字母的最长子串。

解题思路
滑动窗口的右边界不断的右移，只要没有重复的字符，就持续向右扩大窗口边界。
一旦出现了重复字符，就需要缩小左边界至重复字符之后，然后继续移动右边界滑动窗口。
以此类推，每次移动需要计算当前长度，并判断是否需要更新最大长度，最终最大的值就是题目中的所求。
"""


def no_repeat_longest_substring(_string):
    left_index = 0      # 滑块左侧索引位置
    s_right_indexs = {}   # 记录每个字符最新的索引值
    max_length = 0      # 最大长度

    for cur_index in range(len(_string)):
        if _string[cur_index] in s_right_indexs:
            # 获取重复字符左边界后1位字符的索引（也就是【一旦出现了重复字符，就需要缩小左边界至重复字符之后】）
            new_left_index = s_right_indexs[_string[cur_index]] + 1
            # 如果该值大于当前滑块左边界值，则覆盖原边界值
            left_index = max(new_left_index, left_index)
        # 获取当前字符与左边界值的长度
        cur_s_length = cur_index - left_index + 1
        max_length = max(cur_s_length, max_length)
        # 刷新字符索引值
        s_right_indexs[_string[cur_index]] = cur_index
    return max_length


l = "abcabcbb"
print(no_repeat_longest_substring(l))
l = "bbbbb"
print(no_repeat_longest_substring(l))
l = "pwwkew"
print(no_repeat_longest_substring(l))
